package com.example.threadPool;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Description : TODO
 * @Author : ZYX
 * @Date : 2022/6/16 15:39
 * @Version : 1.0
 **/
@Configuration
@Slf4j
public class MyThreadPoolExecutorConfig {

    @Value("${threadPoolExecutorConfig.corePoolSize}")
    private int corePoolSize;

    @Value("${threadPoolExecutorConfig.maximumPoolSize}")
    private int maximumPoolSize;

    @Value("${threadPoolExecutorConfig.keepAliveTime}")
    private int keepAliveTime;

    @Value("${threadPoolExecutorConfig.capacity}")
    private int capacity;

    @Value("${threadPoolExecutorConfig.namePrefix}")
    private String namePrefix;

    class MyThreadPoolFactory implements ThreadFactory {
        private  final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        MyThreadPoolFactory(String name) {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
            if (null == name || name.isEmpty()) {
                name = "pool";
            }
            namePrefix = name + "-thread-" + poolNumber.getAndIncrement();
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
            if (t.isDaemon()){
                t.setDaemon(false);
            }

            if (t.getPriority() != Thread.NORM_PRIORITY){
                t.setPriority(Thread.NORM_PRIORITY);
            }
            return t;
        }
    }

    class MyRejectedExecutionHandler implements RejectedExecutionHandler{

        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            //打印被拒绝的任务
            log.info("任务被拒绝 {},CompletedTaskCount已完成执行的大致任务总数 {},ActiveCount正在主动执行任务的线程的大致数量{}," +
                            "CorePoolSize核心线程数{},LargestPoolSize曾经同时进入池中的最大线程数 {},MaximumPoolSize允许的最大线程数{}," +
                            "QueueSize{},TaskCount已安排执行的大致任务总数{}",r.toString(),executor.getCompletedTaskCount(),
                    executor.getActiveCount(),executor.getCorePoolSize(),executor.getLargestPoolSize(),executor.getMaximumPoolSize(),
                    executor.getQueue().size(),executor.getTaskCount());
        }
    }


    @Bean
    public ExecutorService getThreadPool(){
        log.info("初始化线程池 corePoolSize {},maximumPoolSize{},keepAliveTime {},capacity{},namePrefix{}",corePoolSize,maximumPoolSize,keepAliveTime,capacity,namePrefix);
        return  new MyThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(capacity),new MyThreadPoolFactory(namePrefix),new MyRejectedExecutionHandler());
    }

}
